<template>
  <div class="flex flex-col items-center p-4">
    <!-- 二维码显示区 -->
    <div class="w-full border border-gray-200 rounded-md p-6 flex flex-col items-center justify-center min-h-[320px]">
      <!-- 加载中 -->
      <div v-if="loading" class="flex flex-col items-center justify-center h-64">
        <el-icon class="animate-spin text-primary mb-2">
          <Loading />
        </el-icon>
        <span class="text-gray-500">正在获取扫码二维码...</span>
      </div>

      <!-- 二维码已获取（PC专用） -->
      <div v-else-if="qrUrl" class="flex flex-col items-center">
        <img
          :src="qrUrl"
          alt="微信扫码登录"
          class="w-64 h-64 object-contain mb-3"
          @error="handleQrImgError"
          @load="handleQrImgLoad"
        />
        <p class="text-xs text-gray-400 text-center">
          请用微信扫描上方二维码<br>
          扫码后需关注公众号完成登录<br>
          二维码有效期 <span class="text-primary font-medium">{{ countDown }}</span> 秒
        </p>
      </div>

      <!-- 二维码获取失败/未请求 -->
      <div v-else class="text-center text-gray-500 space-y-4">
        <p v-if="!isRequestInitiated">未发起请求，请点击下方按钮重试</p>
        <p v-else>无法获取扫码二维码</p>
        <el-button
          type="primary"
          size="small"
          @click="fetchQrCode"
          :loading="loading"
        >
          重试获取二维码
        </el-button>
      </div>
    </div>

    <!-- 操作按钮区 -->
    <div class="flex justify-center space-x-4 mt-6">
      <el-button
        type="default"
        size="small"
        @click="handleCancelLogin"
      >
        取消登录
      </el-button>
      <el-button
        type="primary"
        size="small"
        @click="fetchQrCode"
        :loading="loading"
      >
        刷新二维码
      </el-button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, onUnmounted, nextTick } from "vue";
import { ElMessage, ElIcon } from "element-plus";
import { Loading } from "@element-plus/icons-vue";
import Cookies from "js-cookie";
// 1. 确保API路径正确（根据你的项目实际路径修改，建议用绝对路径或正确相对路径）
import { getScanQrCode, getScanStatus } from "../api/index.js"; // 示例：绝对路径

// 对外暴露事件：登录成功/关闭弹窗
const emit = defineEmits(["login-success", "close-modal"]);

// 状态管理：新增请求状态标记，便于排查
const loading = ref(false);
const qrUrl = ref(""); // 二维码图片URL
const scanId = ref(""); // 扫码唯一标识
const countDown = ref(300); // 二维码有效期（秒）
const isRequestInitiated = ref(false); // 是否已发起过请求
// 定时器存储（用ref确保跨函数访问）
let pollTimer = ref(null); 
let countDownTimer = ref(null);

// 2. 组件挂载时强制发起请求（修复核心：确保打开弹窗后立即执行）
onMounted(async () => {
  console.log("[扫码组件] 组件已挂载，开始发起请求");
  // 用nextTick确保DOM渲染完成后再请求，避免异步问题
  await nextTick();
  await fetchQrCode();
});

// 组件卸载前：强制清除所有定时器（关闭弹窗时触发）
onBeforeUnmount(() => {
  clearAllTimers();
  console.log("[扫码组件] 弹窗关闭，已停止所有轮询");
});

// 组件完全卸载：兜底清除定时器
onUnmounted(() => {
  clearAllTimers();
});

/**
 * 1. 获取PC端扫码二维码（核心请求逻辑，确保100%执行）
 */
async function fetchQrCode() {
  try {
    loading.value = true;
    isRequestInitiated.value = true; // 标记为已发起请求
    qrUrl.value = ""; // 清空旧二维码
    clearAllTimers(); // 清除旧定时器

    // 构造请求参数（与后端接口匹配）
    const params = {
      clientIp: Cookies.get("_i") || "unknown", // 避免空值，后端可处理unknown
      fp: Cookies.get("_f") || "unknown",
      timestamp: Date.now()
    };
    console.log("[扫码组件] 发起获取二维码请求，参数:", params); // 打印参数，排查参数问题

    // 3. 调用API获取二维码数据（捕获请求错误，便于排查）
    const res = await getScanQrCode(params);
    console.log("[扫码组件] 获取二维码响应:", res); // 打印响应，排查后端返回问题

    if (res && res.code === 200 && res.data) {
      const { qrImgUrl, scanId: resScanId, expireSeconds } = res.data;
      // 校验关键参数
      if (!qrImgUrl || !resScanId) {
        throw new Error(`二维码数据不完整，缺少关键参数（qrImgUrl:${!!qrImgUrl}, scanId:${!!resScanId}）`);
      }
      // 更新状态
      qrUrl.value = qrImgUrl;
      scanId.value = resScanId;
      countDown.value = expireSeconds || 300;
      // 启动倒计时和轮询
      startCountDown();
      startPollStatus();
    } else {
      throw new Error(`后端返回异常，code:${res?.code || "无"}, msg:${res?.msg || "无"}`);
    }
  } catch (error) {
    console.error("[扫码组件] 获取二维码失败（详细错误）:", error); // 打印完整错误栈
    ElMessage.error(`获取失败：${error.message || "网络异常"}`);
  } finally {
    loading.value = false;
  }
}

/**
 * 2. 启动二维码倒计时
 */
function startCountDown() {
  clearAllTimers(); // 启动前清除旧定时器
  countDownTimer.value = setInterval(() => {
    if (countDown.value <= 0) {
      clearAllTimers();
      ElMessage.warning("二维码已过期，正在刷新...");
      fetchQrCode(); // 自动刷新二维码
      return;
    }
    countDown.value--;
  }, 1000);
}

/**
 * 3. 启动扫码状态轮询（调用后端scanStatus接口）
 */
function startPollStatus() {
  clearAllTimers(); // 启动前清除旧定时器
  pollScanStatus(); // 立即轮询一次
  console.log("[扫码组件] 启动扫码状态轮询，scanId:", scanId.value);
  // 2秒轮询一次（避免频繁请求）
  pollTimer.value = setInterval(pollScanStatus, 2000);
}

/**
 * 4. 轮询扫码状态（核心逻辑）
 */
async function pollScanStatus() {
  if (!scanId.value) {
    clearAllTimers();
    console.log("[扫码组件] 无scanId，停止轮询");
    return;
  }

  try {
    // 调用API查询状态
    const res = await getScanStatus({
      scanId: scanId.value,
      timestamp: Date.now()
    });
    console.log("[扫码组件] 轮询状态响应:", res);

    // 处理后端返回的不同状态
    switch (res?.code) {
      // 登录成功（后端自定义code）
      case "SCAN_LOGIN_SUCCESS":
        handleLoginSuccess(res.data);
        break;
      // 待扫码（继续轮询）
      case "SCAN_PENDING":
        break;
      // 二维码过期
      case "SCAN_EXPIRED":
        clearAllTimers();
        qrUrl.value = "";
        ElMessage.warning(res.msg || "二维码已过期，请重新获取");
        break;
      // 扫码记录不存在
      case "SCAN_NOT_FOUND":
        clearAllTimers();
        qrUrl.value = "";
        ElMessage.error(res.msg || "扫码记录不存在，请重新获取");
        break;
      // 其他错误
      default:
        clearAllTimers();
        ElMessage.error(`查询失败：${res?.msg || "未知错误"}`);
        break;
    }
  } catch (error) {
    console.error("[扫码组件] 轮询状态失败（详细错误）:", error);
    // 网络错误：清除旧定时器，3秒后重试
    if (pollTimer.value) {
      clearInterval(pollTimer.value);
      pollTimer.value = null;
    }
    setTimeout(() => {
      if (scanId.value) startPollStatus();
    }, 3000);
  }
}

/**
 * 5. 处理登录成功
 */
function handleLoginSuccess(data) {
  const { token, nickname, headimgurl, openid } = data;
  if (token) {
    clearAllTimers(); // 停止轮询
    // 通知父组件登录成功
    emit("login-success", {
      token,
      nickname: nickname || "微信用户",
      headimgurl: headimgurl || "",
      openid: openid || ""
    });
  
  }
}

/**
 * 6. 取消登录（关闭弹窗+停止轮询）
 */
function handleCancelLogin() {
  clearAllTimers(); // 先停止轮询
  emit("close-modal"); // 再通知父组件关闭弹窗
}

/**
 * 7. 二维码图片加载失败处理
 */
function handleQrImgError() {
  qrUrl.value = "";
  clearAllTimers();
  ElMessage.error("二维码图片加载失败，请刷新");
}

/**
 * 8. 二维码图片加载成功处理
 */
function handleQrImgLoad() {
  console.log("[扫码组件] 二维码图片加载成功，URL:", qrUrl.value);
}

/**
 * 9. 统一清除所有定时器（核心工具函数）
 */
function clearAllTimers() {
  // 清除轮询定时器
  if (pollTimer.value) {
    clearInterval(pollTimer.value);
    pollTimer.value = null;
    console.log("[扫码组件] 轮询定时器已清除");
  }
  // 清除倒计时定时器
  if (countDownTimer.value) {
    clearInterval(countDownTimer.value);
    countDownTimer.value = null;
    console.log("[扫码组件] 倒计时定时器已清除");
  }
}
</script>

<style scoped>
/* 二维码图片样式优化 */
img {
  display: block;
  margin: 0 auto;
  transition: opacity 0.3s ease;
  border: none;
}
img:hover {
  opacity: 0.95;
}

/* 按钮样式优化 */
.el-button--small {
  padding: 6px 12px;
  border-radius: 4px;
}

/* 文本样式优化 */
.text-primary {
  color: var(--el-color-primary);
}
.text-gray-400 {
  color: var(--el-text-color-secondary);
}
</style>